////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                                            //
//                                                         WNProject                                                          //
//                                                                                                                            //
//            This file is distributed under the BSD 2-Clause open source license. See License.txt for details.               //
//                                                                                                                            //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#define NOMINMAX

#include "WNScripting/inc/WNFunctionHeaderList.h"
#include "WNScripting/inc/WNLLVMHelpers.h"
#include "WNScripting/inc/WNFunctionDecl.h"
#include "WNScripting/inc/WNDataType.h"
#include "WNMemory/inc/WNAllocation.h"

using namespace WNScripting;

WNFunctionHeaderList::WNFunctionHeaderList(WN_SIZE_T _startLine, 
                                           WN_SIZE_T _endLine, 
                                           WN_SIZE_T _startChar, 
                                           WN_SIZE_T _endChar, 
                                           WNDataType* _dataType, 
                                           WNIdentifierElement _elem, 
                                           WNFunctionHeaderList* _fSubList) :
    WNParseNode(_startLine, _endLine, _startChar, _endChar),
    mIdentifier(_elem),
    mDataType(_dataType),
    mSubList(_fSubList) {
}

WNFunctionHeaderList::WNFunctionHeaderList(WN_SIZE_T _startLine, 
                                           WN_SIZE_T _endLine, 
                                           WN_SIZE_T _startChar, 
                                           WN_SIZE_T _endChar, 
                                           WNDataType* _dataType, 
                                           WNIdentifierElement _elem) :
        WNParseNode(_startLine, _endLine, _startChar, _endChar),
        mIdentifier(_elem),
        mDataType(_dataType),
        mSubList(WN_NULL) {
}

WNFunctionHeaderList::~WNFunctionHeaderList(){
    if (mDataType != WN_NULL) {
        WN_DELETE(mDataType);
    }
}


llvm::Value* WNFunctionHeaderList::OptimizeAndGenerate(WNScriptingEngineData& _scriptingData, WNFunctionDecl* _functionDecl) {
    WN_DEBUG_ASSERT(mDataType != WN_NULL);
    OptimizeAndGeneratePrivate(_scriptingData, _functionDecl, mFunctionVals);
    return(WN_NULL);
}

void WNFunctionHeaderList::OptimizeAndGeneratePrivate(WNScriptingEngineData& _scriptingData, WNFunctionDecl* _functionDecl, std::vector<WNFunctionVal>& _fillList) {
    WNParseNode::OptimizeAndGenerate(_scriptingData, _functionDecl);
    WN_DEBUG_ASSERT(mDataType != WN_NULL);
    mDataType->OptimizeAndGenerate(_scriptingData, _functionDecl);
    WNTypeElement type = mDataType->GetType();
    WNFunctionVal v = { mIdentifier, type };
    _fillList.push_back(v);
    if (mSubList) {
        mSubList->OptimizeAndGeneratePrivate(_scriptingData, _functionDecl, _fillList);
    }
    WN_DELETE(mDataType);
    mDataType = WN_NULL;
    WN_DELETE(mSubList);
    mSubList = WN_NULL;
}

const std::vector<WNFunctionHeaderList::WNFunctionVal>& WNFunctionHeaderList::GetFunctionParameters() {
    WN_DEBUG_ASSERT(mOptimized);
    return(mFunctionVals);
}
